package cn.lingyangwl.agile.auth.gituser;

import cn.hutool.core.util.StrUtil;
import cn.lingyangwl.agile.auth.assembly.ThirdAuthAssembly;
import cn.lingyangwl.agile.auth.model.rqrs.third.AuthUrlGetReq;
import cn.lingyangwl.agile.auth.model.rqrs.third.ThirdAuthResp;
import cn.lingyangwl.agile.auth.model.rqrs.third.ThirdAuthUser;
import cn.lingyangwl.agile.auth.model.rqrs.third.ThirdLoginReq;
import cn.lingyangwl.framework.core.response.Resp;
import cn.lingyangwl.framework.security.ratelimit.LimitTypeEnum;
import cn.lingyangwl.framework.security.ratelimit.RateLimit;
import cn.lingyangwl.framework.tool.core.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.enums.scope.AuthGiteeScope;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthGiteeRequest;
import me.zhyd.oauth.utils.AuthScopeUtils;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 *
 * @author shenguangyang
 */
@Slf4j
@RestController
@RequestMapping("/gitUser")
public class GitUserController {
    @Resource
    private GitUserService gitUserService;
    @Resource
    private GitUserProperties properties;
    @Resource
    private ThirdAuthAssembly thirdAuthAssembly;

    public AuthGiteeRequest getAuthGiteeRequest(String backUrl) {
        GitUserProperties.Gitee gitee = properties.getGitee();
        String redirectUri = properties.getGitee().getRedirectUri() + "?backUrl=" + StrUtil.emptyToDefault(backUrl, "/");
        return new AuthGiteeRequest(AuthConfig.builder()
                .clientId(gitee.getClientId())
                .clientSecret(gitee.getClientSecret())
                .redirectUri(redirectUri)
                .scopes(AuthScopeUtils.getScopes(AuthGiteeScope.USER_INFO))
                .build());
    }

    /**
     * 获取第三方登录的地址
     */
    @GetMapping("/authorize/{source}")
    public Resp<ThirdAuthResp> authorize(@PathVariable("source") String source, AuthUrlGetReq req) {
        AuthGiteeRequest authRequest = getAuthGiteeRequest(req.getBackUrl());
        String url = authRequest.authorize(AuthStateUtils.createState());
        log.info("authorize-url: {}", url);
        return Resp.ok(ThirdAuthResp.builder().pageUrl(url).build());
    }

    @GetMapping("/oauthCallback/{source}")
    @SuppressWarnings("unchecked")
    public void login(@PathVariable("source") String source, ThirdLoginReq req, HttpServletRequest request, HttpServletResponse response) throws Exception {

        AuthCallback callbackReq = thirdAuthAssembly.toAuthCallback(req);

        @SuppressWarnings("unchecked")
        AuthResponse<AuthUser> login = getAuthGiteeRequest(req.getBackUrl()).login(callbackReq);

        if (!login.ok()) {
            log.error("third login: {}", login.getMsg());
            throw new BizException("三方授权失败, 请重新发起登录");
        }

        ThirdAuthUser authUser = thirdAuthAssembly.toThirdAuthUser(login.getData());

        String redirect = request.getParameterMap().get("backUrl")[0];
        Long gitUserId = gitUserService.saveOrUpdateUser(authUser);
        String backUrl = redirect + (redirect.contains("?") ? "&" : "?" + "gitUserId=" + gitUserId);
        log.info("backUrl: {}", backUrl);
        response.sendRedirect(backUrl);
    }

    @GetMapping("/getUser")
    @RateLimit(key = "git_user", time = 60, count = 20, limitType = LimitTypeEnum.IP)
    public Resp<GitUser> getUser(@RequestParam("id") Long id) {
        return Resp.ok(gitUserService.getUser(id));
    }
}
